/*
 * WF282.c
 *
 *  Created on: 2020年8月4日
 *      Author: ITry
 */
#include <string.h>
#include "SoftIIc.h"
#include "WF282.h"

/****************** compensation scale factors***************************************/
#define WF282_KP_1      524288      //single
#define WF282_KP_2      1572684     //low power
#define WF282_KP_4      3670016
#define WF282_KP_8      7864320
#define WF282_KP_16     253952      //standard
#define WF282_KP_32     516096
#define WF282_KP_64     1040384     //high precision
#define WF282_KP_128    2088960

#define WF282_KT_1      524288      //single
#define WF282_KT_2      1572684     //low power
#define WF282_KT_4      3670016
#define WF282_KT_8      7864320
#define WF282_KT_16     253952      //standard
#define WF282_KT_32     516096
#define WF282_KT_64     1040384     //high precision
#define WF282_KT_128    2088960
/****************** var***************************************/
#define IIC_DEVICE_ADDR		(0x77 << 1)
#define WF282_MEAS_CFG    0x08
#define WF282_PSR_BX      0x00
#define WF282_TMP_BX      0x03
#define WF282_PRS_CFG     0x06
#define WF282_TMP_CFG     0x07
#define WF282_CFG_REG   0x09
#define WF282_SOFT_RST    0x0c
#define WF282_ID_CODE   0x0d
/****************** var***************************************/
long WF282_C0;
long WF282_C1;
long WF282_C00;
long WF282_C01;
long WF282_C10;
long WF282_C11;
long WF282_C20;
long WF282_C21;
long WF282_C30;

uint8_t IIC_ReadNByte(uint8_t start_addr, uint8_t data_num, uint8_t *readData);
uint8_t IIC_WriteNByte(uint8_t start_addr, uint8_t data_num, const uint8_t *reg_data);

uint8_t WF282_Get_Calib_Param() {
	uint8_t err = 0;
	uint8_t buf[18];
	err = IIC_ReadNByte(0x10, 18, buf);
	WF282_C0 = (((long)buf[0]) << 4) + ((buf[1] >> 4) & 0x0F);
	if (WF282_C0 > 0x7ff)         //> 0x800
		WF282_C0 = WF282_C0 - 0x1000;

	WF282_C1 = buf[2]+(((long)(buf[1] & 0x0F)) << 8);
	if (WF282_C1 > 0x7ff)         //> 0x800
		WF282_C1 = WF282_C1 - 0x1000;

	WF282_C00 = (((long)((buf[3]<<8) + buf[4]))<<4)+((buf[5]>>4)&0x0F);
	if (WF282_C00 > 0x7ffff)        //> 0x80000
		WF282_C00 = WF282_C00 - 0x100000;

	WF282_C10 = (((long)((buf[5]&0x0F)<<8)+buf[6])<<8)+buf[7];
	if (WF282_C10 > 0x7ffff)        //> 0x80000
		WF282_C10 = WF282_C10 - 0x100000;

	WF282_C01 = buf[9] + (((long)buf[8]) << 8);
	if (WF282_C01 > 0x7fff)         //> 0x8000
		WF282_C01 = WF282_C01 - 0x10000;

	WF282_C11 = buf[11] + (((long)buf[10]) << 8);
	if (WF282_C11 > 0x7fff)         //> 0x8000
		WF282_C11 = WF282_C11 - 0x10000;

	WF282_C20 = buf[13] + (((long)buf[12]) << 8);
	if (WF282_C20 > 0x7fff)         //> 0x8000
		WF282_C20 = WF282_C20 - 0x10000;

	WF282_C21 = buf[15] + (((long)buf[14]) << 8);
	if (WF282_C21 > 0x7fff)         //> 0x8000
		WF282_C21 = WF282_C21 - 0x10000;

	WF282_C30 = buf[17] + (((long)buf[16]) << 8);
	if (WF282_C30 > 0x7fff)         //> 0x8000
		WF282_C30 = WF282_C30 - 0x10000;

	return err;
}

uint8_t WF282_Read_ID(void) {
//	uint8_t err = 0;
	uint8_t buf[1];
	 IIC_ReadNByte(WF282_ID_CODE, 1, buf);
	return buf[0];
}

uint8_t WF282_Get_Data_Press_Temp(uint8_t data_num, double *readData) {
	uint8_t err = 0;
	uint8_t buf[3];
	long  WF282_NewPressData,WF282_NewTempData;
	double tmpData, Traw_sc, Praw_sc;
	if (readData == NULL || data_num == 0) {
		return 1;
	}
	//API_WF282_Read_Temperature
	buf[0] = 0x02;
	err = IIC_WriteNByte(WF282_MEAS_CFG, 1, buf);
	HAL_Delay(250);
	err = IIC_ReadNByte(WF282_TMP_BX, 3, buf);
	WF282_NewTempData = buf[0];
	WF282_NewTempData <<= 8;
	WF282_NewTempData |= buf[1];
	WF282_NewTempData <<= 8;
	WF282_NewTempData |= buf[2];
	if (WF282_NewTempData > 0x7FFFFF) {        //(2^23-1)  > 0x800000
		WF282_NewTempData = WF282_NewTempData - 0x1000000;  //2^24
	}
//	printf("WF282_NewTempData:%f\r\n",WF282_NewTempData);
	//API_WF282_Read_Press
	buf[0] = 0x01;
	err = IIC_WriteNByte(WF282_MEAS_CFG, 1, buf);
	HAL_Delay(250);
	err = IIC_ReadNByte(WF282_PSR_BX, 3, buf);
	WF282_NewPressData = buf[0];
	WF282_NewPressData <<= 8;
	WF282_NewPressData |= buf[1];
	WF282_NewPressData <<= 8;
	WF282_NewPressData |= buf[2];

	if (WF282_NewPressData > 0x7FFFFF) {            //(2^23-1)  > 0x800000
		WF282_NewPressData = WF282_NewPressData - 0x1000000;  //2^24
	}
	//
	Traw_sc = ((double) WF282_NewTempData) / WF282_KT_128;
	tmpData =  WF282_C0 * 0.5 +  WF282_C1 * Traw_sc;
	readData[1] = tmpData;

	Praw_sc = ((double) WF282_NewPressData) / WF282_KP_128;
	tmpData = ( WF282_C00) + Praw_sc * ( WF282_C10 + Praw_sc * ( WF282_C20 + Praw_sc * WF282_C30))
			+ Traw_sc *  WF282_C01 + Traw_sc * Praw_sc * ( WF282_C11 + Praw_sc +  WF282_C21);
	readData[0] = tmpData;
	return err;
}

uint8_t WF282_Init(void) {
	uint8_t err = 0;
	uint8_t buf[1];
	//复位
	buf[0] = 0x09;
	err = IIC_WriteNByte(WF282_SOFT_RST, 1, buf);
	HAL_Delay(100);
	//初始化系数
	err = WF282_Get_Calib_Param();
	//
	buf[0] = 0x07;
	err = IIC_WriteNByte(WF282_PRS_CFG, 1, buf);
	HAL_Delay(1);
	buf[0] = 0x87;
	err = IIC_WriteNByte(WF282_TMP_CFG, 1, buf);
	HAL_Delay(1);
	buf[0] = 0x0C;
	err = IIC_WriteNByte(WF282_CFG_REG, 1, buf);
	HAL_Delay(1);
	return err;
}

uint8_t IIC_ReadNByte(uint8_t start_addr, uint8_t data_num, uint8_t *readData) {
	uint8_t i = 0;
	uint8_t err = 0;
	if (readData == NULL || data_num == 0) {
		return 1;
	}

	iic_start();
	iic_sendbyte(IIC_DEVICE_ADDR | IIC_WRITE);
	err = iic_wait_ack();
	iic_sendbyte(start_addr);
	err = iic_wait_ack();
	iic_start();
	iic_sendbyte(IIC_DEVICE_ADDR | IIC_READ);
	err = iic_wait_ack();
	for (i = 0; i < data_num; i++) {
		readData[i] = iic_readbyte(i != (data_num - 1));
	}
	iic_stop();
	return err;
}

uint8_t IIC_WriteNByte(uint8_t start_addr, uint8_t data_num, const uint8_t *reg_data) {
	uint8_t i = 0;
	uint8_t err = 0;
	if (reg_data == NULL || data_num == 0) {
		return 1;
	}
	iic_start();
	iic_sendbyte(IIC_DEVICE_ADDR | IIC_WRITE);
	err = iic_wait_ack();
	iic_sendbyte(start_addr);
	err = iic_wait_ack();
	for (i = 0; i < data_num; i++) {
		iic_sendbyte(reg_data[i]);
		err = iic_wait_ack();
	}
	iic_stop();
	return err;
}
